package org.wzh.spring.aop.demo3;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AudienceAround {

	@Pointcut("execution(** org.wzh.spring.aop.demo2.Performance.perform(..))")
	public void performance() {}

	/**
	 * 环绕通知方法
	 * 在这里,@Around注解表明watchPerformance()方法会作为performance()切点的环绕通知.
	 * 可以看到,这个通知所达到的效果与之前的前置通知和后置通知是一样的.但是,现在他们位于同一个方法中,不想之前那样分散在四个不同的通知方法里面.
	 * 
	 * 关于这个新的通知方法,你首先注意到的可能是它接受ProceedingJoinPoint作为参数.这个对象是必须要有的,因为你要在通知中通过它来调用
	 * 被通知的方法.通知方法中可以做任何的事情,当要将控制权交给被通知的方法时,它需要调用ProceedingJoinPoint的proceed()方法.
	 * 需要注意的是,别忘记调用proceed()方法,如果不调这个方法的话,那么你的通知实际上会阻塞被通知方法的调用.有可能这就是你想要的效果,但更多的情况是你
	 * 希望在某个点上执行被通知的方法.
	 * 你可以不调用proceed()方法,从而阻塞对被通知方法的访问,与之类似,你也可以在通知中对它进行多次调用.要这样做的一个场景就是实现重试逻辑.也就是
	 * 在被通知方法失败后,进行重复尝试.
	 * @param 
	 */
	@Around("performance()")
	public void watchPerformance(ProceedingJoinPoint jp) {
		try {
			System.out.println("Silencing cell phones --  AudienceAround");
			System.out.println("Taking seats --  AudienceAround");
			jp.proceed();
			System.out.println("CLAP CLAP CLAP!!! --  AudienceAround");
		} catch (Throwable e) {
			System.out.println("Demanding a refund --  AudienceAround");                                                                                       
		}
		
	}
	
}
